/*
 * Copyright (c) 2017 22420103@QQ.COM 版权所有
 */
package com.lehe.service.impl;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.lehe.common.utils.CalculateUtil;
import com.lehe.dao.*;
import com.lehe.entry.*;
import com.lehe.entry.dbbean.GameUserDto;
import com.lehe.entry.dbbean.GoldDetailDto;
import com.lehe.util.TagUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.lehe.common.Contants;
import com.lehe.common.crypt.Md5Encrypt;
import com.lehe.common.exceptions.LHAdminException;
import com.lehe.common.exceptions.LHException;
import com.lehe.common.utils.StringUtil;

/**
 * 用户代理操作
 *
 * @author 王丹
 * @since 2017-02-26
 */
@Transactional
@Service
public class UserManagerService extends AbstractService {

    @Autowired
    private AgentInfoDao agentInfoDao;
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
	private UserManagerDao userManagerDao;  
    @Autowired
	private GoldDetailDao goldDetailDao;
    @Autowired
	private UserInfoDao userInfoDao;
    
    @Autowired
    private AdminUserMappingService adminUserMappingService;
    @Autowired
    private UserChargeGoldCoinLogDao userChargeGoldCoinLogDao;
    @Autowired
    private AdminUserDao adminUserDao;

    /**
     * 设置代理
     * @param userId 要设置成代理的玩家id
     * @param agentId 要设置成代理的玩家上级代理id或agentid
     * @param adminUserId 将新设置成代理的玩家关联到后台用户的后台用户id
     * @param roleId 如果权限为1的话，就是管理员角色，不需要插入用户关联数据
     * @return
     * @throws LHException 
     */
    public void createAgent(Long userId, Long agentId,Integer userLvel,Long adminUserId, Long roleId) throws LHAdminException{
        
        //查询出要设置代理的玩家信息
        UserInfoDto playerInfo = userInfoService.queryUserInfo(userId, null);
        
        if(playerInfo == null){
        	throw new LHAdminException("玩家id【"+userId+"】信息不存在");
        }
        
        if(!playerInfo.getAgentId().equals(0L)){
        	throw new LHAdminException("玩家id【"+userId+"】已经是代理，不能再设置为代理");
        }
        
        //查询出要设置代理玩家的上级代理信息,agentId参数接收的值可能为userid，也可能为agentid，因此先根据userid查询
        UserInfoDto fatherInfo = null;
        if(!agentId.equals(0L)){
        	fatherInfo = userInfoService.queryUserInfo(agentId, null);
            //没查询到再根据agentid查询
            if(fatherInfo == null){
            	fatherInfo = userInfoService.queryUserInfoByAgentId(agentId);
            }
            
            if(fatherInfo == null){
            	throw new LHAdminException("上级代理id【"+agentId+"】信息不存在");
            }
            if(null == fatherInfo.getAgentId() || fatherInfo.getAgentId().intValue() <= 0){
                throw new LHAdminException("上级代理id【"+agentId+"】不是代理用户");
            }
            if(!StringUtil.isCreateAgent(fatherInfo.getUserLevel())){
            	throw new LHAdminException("上级代理id【"+agentId+"】代理级别不够");
            }
        }else{
        	throw new LHAdminException("上级代理id不能为0");
        }
        
        //更新玩家用户表
        UserInfoDto updateDto = new UserInfoDto();
        updateDto.setUserId(playerInfo.getUserId());
        updateDto.setAgentId(playerInfo.getUserId());
        updateDto.setFatherAgentId(fatherInfo == null?0L:fatherInfo.getAgentId());
        updateDto.setUserLevel(userLvel);
        userInfoService.updateAccountByUserId(updateDto);

        //插入AgentInfo信息
        AgentInfoDto agentSubInfoDto = new AgentInfoDto();
        agentSubInfoDto.setUserId(updateDto.getUserId());
        agentSubInfoDto.setAgentId(updateDto.getAgentId());
        agentSubInfoDto.setfAgentId(fatherInfo == null?0L:fatherInfo.getAgentId());
        agentSubInfoDto.setAgentPassword(Md5Encrypt.md5(" "));//??密码哪里来
        agentSubInfoDto.setPhoneNum("");//??哪里来
        agentSubInfoDto.setLoginRight(updateDto.getUserLevel());
        insertAgentInfo(agentSubInfoDto);
        
        //插入后台用户与玩家用户关联表数据
        if(1 != roleId){
            AdminUserMappingDto d = new AdminUserMappingDto();
            d.setAdminUserId(adminUserId);
            d.setUserId(userId);
            adminUserMappingService.insertAdminUserMapping(d);
        }

    }

    /**
     * 后台给玩家充值，管理员或者员工充值玩家
     * @param userId 充值的目标玩家
     * @param count 充值数量
     * @param count 充值金额
     * @param adminUserSessionDto 后台登录用户
     * @throws LHAdminException
     */
    public void chargeJB(Long userId, Long count, Double money, AdminUserSessionDto adminUserSessionDto) throws LHAdminException{
        if(!TagUtil.hasButtonRole("rechargeButton")){
            throw new LHAdminException("无充值权限");
        }
        if(count<0 && 1!=adminUserSessionDto.getRoleId()){
            throw new LHAdminException("无扣除权限");
        }
        UserInfoDto dest = userInfoService.queryUserInfo(userId,null);
        if(dest == null){
            throw new LHAdminException("要充值的目标玩家不存在");
        }
        if(count<0 && dest.getGoldCoinCount() < -count){
            throw new LHAdminException("要充值的目标玩家金币数小于扣除数");
        }
        AdminUserDto adminUserDto = adminUserDao.queryById(adminUserSessionDto.getId());
        if(adminUserDto.getCurrentGoldCoins() < count){
            if(1==adminUserSessionDto.getRoleId()){
                logger.warn("管理员用户当前金币小于充值金币");
                adminUserDto.setCurrentGoldCoins(adminUserDto.getCurrentGoldCoins() + 99999999999L);
                adminUserDto.setGoldCoins(adminUserDto.getGoldCoins() + 99999999999L);
            }else{
                throw new LHAdminException("后台用户当前金币小于充值金币");
            }
        }
        userManagerDao.chargeJB(userId, count);
        adminUserDto.setCurrentGoldCoins(adminUserDto.getCurrentGoldCoins() - count);
        if(null!=money && money > 0){
            adminUserDto.setGoldMoney(CalculateUtil.add(adminUserDto.getGoldMoney(), money));
        }
        adminUserDao.updateAdminUserById(adminUserDto);
        UserChargeGoldCoinLogDto userChargeGoldCoinLogDto = new UserChargeGoldCoinLogDto();
        userChargeGoldCoinLogDto.setJuniorUserId(userId);
        /*if(1==adminUserSessionDto.getRoleId()){
            userChargeGoldCoinLogDto.setSuperiorUserId(Contants.ADMIN_AGENT_ID);
            userChargeGoldCoinLogDto.setSuperiorAgentId(Contants.ADMIN_AGENT_ID);
        }else {
            userChargeGoldCoinLogDto.setSuperiorUserId(adminUserSessionDto.getId());
            userChargeGoldCoinLogDto.setSuperiorAgentId(adminUserSessionDto.getId());
        }*/
        userChargeGoldCoinLogDto.setSuperiorUserId(adminUserSessionDto.getId());
        userChargeGoldCoinLogDto.setSuperiorAgentId(adminUserSessionDto.getId());
        userChargeGoldCoinLogDto.setChargeCount(count);
        userChargeGoldCoinLogDto.setChargeMoney(money);
        userChargeGoldCoinLogDto.setOpType(Contants.USER_CHARGE_OP_TYPE_ADD);
        if(count<0){
            userChargeGoldCoinLogDto.setChargeCount(-count);
            //userChargeGoldCoinLogDto.setChargeMoney(-money);
            userChargeGoldCoinLogDto.setOpType(Contants.USER_CHARGE_OP_TYPE_SUB);
        }
        userChargeGoldCoinLogDto.setSourceType(Contants.USER_CHARGE_SOURCE_TYPE_ADMIN_TO_PLAYER);
        userChargeGoldCoinLogDto.setCreateTime(LocalDateTime.now());
        userChargeGoldCoinLogDao.insert(userChargeGoldCoinLogDto);
    }

    


    /**wq
     * 后台给玩家充值，管理员或者员工充值玩家
     * @param userId 充值的目标玩家
     * @param count 充值数量
     * @param count 充值金额
     * @param adminUserSessionDto 后台登录用户
     * @throws LHAdminException
     */
    public void chargeJBS(Long userId, Long count, Double money, AdminUserSessionDto adminUserSessionDto) throws LHAdminException{
        if(!TagUtil.hasButtonRole("rechargeButton")){
            throw new LHAdminException("无充值权限");
        }
        if(count<0 && 1!=adminUserSessionDto.getRoleId()){
            throw new LHAdminException("无扣除权限");
        }
        UserInfoDto dest = userInfoService.queryUserInfo(userId,null);
        if(dest == null){
            throw new LHAdminException("要充值的目标玩家不存在");
        }
        GameUserDto queryGameUserByUser = goldDetailDao.queryGameUserByUser(userId);
        
        if(count<0 && dest.getGoldCoinCount() < -count){
            throw new LHAdminException("要充值的目标玩家金币数小于扣除数");
        }
        AdminUserDto adminUserDto = adminUserDao.queryById(adminUserSessionDto.getId());
        if(adminUserDto.getCurrentGoldCoins() < count){
            if(1==adminUserSessionDto.getRoleId()){
                logger.warn("管理员用户当前金币小于充值金币");
                adminUserDto.setCurrentGoldCoins(adminUserDto.getCurrentGoldCoins() + 99999999999L);
                adminUserDto.setGoldCoins(adminUserDto.getGoldCoins() + 99999999999L);
            }else{
                throw new LHAdminException("后台用户当前金币小于充值金币");
            }
        }
        userManagerDao.chargeJB(userId, count);
        adminUserDto.setCurrentGoldCoins(adminUserDto.getCurrentGoldCoins() - count);
        if(null!=money && money > 0){
            adminUserDto.setGoldMoney(CalculateUtil.add(adminUserDto.getGoldMoney(), money));
        }
        adminUserDao.updateAdminUserById(adminUserDto);
        
        
        GoldDetailDto goldDetailDto = new GoldDetailDto();
        goldDetailDto.setUserId(userId);
        goldDetailDto.setAmt(count);
        goldDetailDto.setBalance(dest.getGoldCoinCount()+count);
        goldDetailDto.setBusiType(1);
        goldDetailDto.setUserType(queryGameUserByUser==null?0:queryGameUserByUser.getUtype().longValue());
        goldDetailDto.setpId(null);
        goldDetailDto.setCrtOpr(adminUserSessionDto.getId());
        goldDetailDto.setCrtDate(new Date().toLocaleString());
        goldDetailDao.insert(goldDetailDto);
        /*UserChargeGoldCoinLogDto userChargeGoldCoinLogDto = new UserChargeGoldCoinLogDto();
        userChargeGoldCoinLogDto.setJuniorUserId(userId);
        
        userChargeGoldCoinLogDto.setSuperiorUserId(adminUserSessionDto.getId());
        userChargeGoldCoinLogDto.setSuperiorAgentId(adminUserSessionDto.getId());
        userChargeGoldCoinLogDto.setChargeCount(count);
        userChargeGoldCoinLogDto.setChargeMoney(money);
        userChargeGoldCoinLogDto.setOpType(Contants.USER_CHARGE_OP_TYPE_ADD);
        if(count<0){
            userChargeGoldCoinLogDto.setChargeCount(-count);
            //userChargeGoldCoinLogDto.setChargeMoney(-money);
            userChargeGoldCoinLogDto.setOpType(Contants.USER_CHARGE_OP_TYPE_SUB);
        }
        userChargeGoldCoinLogDto.setSourceType(Contants.USER_CHARGE_SOURCE_TYPE_ADMIN_TO_PLAYER);
        userChargeGoldCoinLogDto.setCreateTime(LocalDateTime.now());
        userChargeGoldCoinLogDao.insert(userChargeGoldCoinLogDto);*/
    }
    
    
    /**wq
     * 后台给玩家充值，管理员或者员工充值玩家
     * @param userId 充值的目标玩家
     * @param count 充值数量
     * @param count 充值金额
     * @param adminUserSessionDto 后台登录用户
     * @throws LHAdminException
     */
    public void chargeYYHJBS(Long userId, Long count, Double money, AdminUserSessionDto adminUserSessionDto) throws LHAdminException{
        if(1!=adminUserSessionDto.getRoleId()){
            throw new LHAdminException("无运营号充值权限");
        }
        AdminUserDto adminUserDto = adminUserDao.queryById(userId);
        if(adminUserDto == null){
            throw new LHAdminException("要充值的运营号不存在");
        }
        
        if(count<0 && adminUserDto.getScore() < -count){
            throw new LHAdminException("要充值的运营号金币数小于扣除数");
        }
        adminUserDto.setScore((int) (adminUserDto.getScore() + count));

        adminUserDao.updateAdminUserById(adminUserDto);
        
        
        GoldDetailDto goldDetailDto = new GoldDetailDto();
        goldDetailDto.setUserId(userId);
        goldDetailDto.setAmt(count);
        goldDetailDto.setBalance(adminUserDto.getCurrentGoldCoins() + count);
        goldDetailDto.setBusiType(1);
        goldDetailDto.setUserType(2l);
        goldDetailDto.setpId(null);
        goldDetailDto.setCrtOpr(adminUserSessionDto.getId());
        goldDetailDto.setCrtDate(new Date().toLocaleString());
        goldDetailDao.insert(goldDetailDto);
    }
    
    /**
     * 插入代理表数据
     * @param agentInfoDto
     * @return
     */
    public int insertAgentInfo(AgentInfoDto agentInfoDto){
        return agentInfoDao.insertAgentInfo(agentInfoDto);
    }
    /**
     * @Description: edit wuqi back
    * @author:wq 
    * @date:2018年3月6日
    * @parameter:
     */
    public Map<String,Object> queryIndexData(List<Long> ids,List<Long> agentIds,Long adminUserId){
		
		//在线人数
		Integer onlineCount = userManagerDao.queryOnlineCount();
		//下属玩家
		Integer subPlayerCount = userManagerDao.queryUserPlayerCount(null,null,null, ids);
		//下属代理
		Integer subAgentCount = ids.size();
		if(subAgentCount == 0){
			subAgentCount = userManagerDao.queryAllAgentCount();
		}
		//微信充值总额
		String totalFeeCountStr = userManagerDao.queryTotalFeeCountByAgentIds(ids,agentIds);
		//今日微信充值总额
		String todayTotalFeeCount = userManagerDao.queryTotalFeeCountByAgentIdsToday(ids,agentIds);
		//今日充值笔数
		//Integer todayTotalCount = userManagerDao.queryTotalCountByAgentIdsToday(ids,agentIds);
        //金币充值总额
        String totalGoldFeeCountStr = "0.00";
        //今日金币充值总额
        String todayTotaGoldlFeeCount = "0.00";
		if(ids.isEmpty()){
            totalGoldFeeCountStr = userManagerDao.queryAdminUserChargeSum(null,null,null);
            todayTotaGoldlFeeCount = userManagerDao.queryAdminUserChargeSum(null,LocalDate.now().toString(),LocalDate.now().toString());
        }else{
            totalGoldFeeCountStr = userManagerDao.queryAdminUserChargeSum(adminUserId.toString(),null,null);
            todayTotaGoldlFeeCount = userManagerDao.queryAdminUserChargeSum(adminUserId.toString(),LocalDate.now().toString(),LocalDate.now().toString());
        }

		List<UserPayDetailDto> newest = userManagerDao.queryNewestCharge(ids,agentIds);
		
		Map<String,Object> result = new HashMap<String,Object>();
		result.put("onlineCount", onlineCount);
		result.put("subPlayerCount", subPlayerCount);
		result.put("subAgentCount", subAgentCount);
		result.put("totalFeeCountStr", totalFeeCountStr);
		result.put("todayTotalFeeCount", todayTotalFeeCount);
		result.put("totalGoldFeeCountStr", totalGoldFeeCountStr);
        result.put("todayTotaGoldlFeeCount", todayTotaGoldlFeeCount);
		result.put("newest", newest);
		
		return result;
	}

    /**
     * @Description: edit wuqi
    * @author:wq 
     * @param adminUserId 
     * @param topId 
    * @date:2018年3月6日
    * @parameter:
     */
    public Map<String,Object> queryIndexData(Long roleId, Long topId){
		if(1l == roleId){
			topId=null;
		}
		//在线人数
		Integer onlineCount = userManagerDao.queryOnlineCount();
		//今日上下分 数据
		UserGoldDetailDto todayGoldDetail= goldDetailDao.queryTotalIndex(topId,true);
		//总上下分 和提成数据
		UserGoldDetailDto sumGoldDetail= goldDetailDao.queryTotalIndex(topId,false);
		//总赠送数据
		UserGoldDetailDto sumGiveScore= goldDetailDao.countGiveScoreIndex(topId,false);
		//今日总税收
		UserGoldDetailDto todayTaxSum= goldDetailDao.countTaxIndex(topId,true);		
		//总税收
		UserGoldDetailDto taxSum= goldDetailDao.countTaxIndex(topId,false);	
		//总余额
		UserGoldDetailDto sumGold= goldDetailDao.sumGoldCoinCount(topId);
		//总玩家
		Integer countAccounts = goldDetailDao.countAccounts(topId);

        List<UserGoldDetailDto> newest = goldDetailDao.queryGoldDetail(null,10,topId);
        
		Map<String,Object> result = new HashMap<String,Object>();
		result.put("onlineCount", onlineCount);//在线人数
		result.put("totalFeeInToday", todayGoldDetail.getInSum());//今日总上分
		result.put("totalFeeOutToday", todayGoldDetail.getOutSum());//今日总下分
		result.put("totalFeeIn", sumGoldDetail.getInSum());//总上分
		result.put("totalFeeOut", sumGoldDetail.getOutSum());//总下分
		result.put("rebateSum", sumGoldDetail.getRebateSum());//总提成
        result.put("sumGiveScore", sumGiveScore.getGiveScoreSum());//总赠送  
        result.put("todayTaxSum", todayTaxSum.getTaxSum());//今日总税收
        result.put("taxSum", taxSum.getTaxSum());//总税收        
		result.put("countAccounts", countAccounts);//总玩家		
		result.put("sumGold", sumGold.getGoldCoinCount());//总余额
		
        result.put("newest", newest);

        
		return result;
	}
	public void deleteAgent(Long userId) throws LHAdminException {
		List<String> ids = new ArrayList<String>();
		ids.add(userId.toString());
		List<UserInfoDto> tmp = userInfoDao.queryUserInfos(ids);
		
		if(tmp == null || tmp.isEmpty()){
			throw new LHAdminException("要解除代理的用户不存在【"+userId+"】");
		}
		
		UserInfoDto user = tmp.get(0);
		
		if(user.getAgentId() == null || user.getAgentId().intValue() == 0){
			throw new LHAdminException("要解除代理的用户还不是代理");
		}
		
		if(user.getAgentId() == null || user.getAgentId().intValue() == 0){
			throw new LHAdminException("要解除代理的用户还不是代理");
		}
		
		//查询下属代理个数
		Integer count = userManagerDao.queryUserAgentCount(null,user.getAgentId(),null,null,null);
		if(count > 0){
			throw new LHAdminException("要解除代理的用户已经有"+count+"个下属代理，不能解除");
		}
		//查询下属玩家个数
		List<Long> tmpIds = new ArrayList<Long>();
		tmpIds.add(userId);
		count = userManagerDao.queryUserPlayerCount(null,null,null,tmpIds);
		if(count > 0){
			throw new LHAdminException("要解除代理的用户已经有"+count+"个下属玩家，不能解除");
		}
		
		//1更新用户agentid为0，代理等级为0
        UserInfoDto updateDto = new UserInfoDto();
        updateDto.setUserId(user.getUserId());
        updateDto.setAgentId(0L);
        updateDto.setUserLevel(0);
        userInfoService.updateAccountByUserId(updateDto);
        
        //2删除AgentInfo
        agentInfoDao.deleteAgentInfoByUserId(user.getUserId());
        
        //删除后台用户与玩家用户关联表数据
        adminUserMappingService.deleteByUserId(user.getUserId());
      
	}

}
